// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use std::net::UdpSocket;
use tauri::{Manager, Window};

#[derive(Clone, serde::Serialize)]
struct Payload {
    data: String,
    address: String
}

#[tauri::command]
fn msg_sender(data: String, address: String) -> Result<String, String> {
    // 创建一个UDP套接字
    let socket = UdpSocket::bind("0.0.0.0:0").map_err(|err| err.to_string())?;
    // 远程服务器的地址和端口
    let server_address = format!("{}:8080", address);
    // 发送数据到服务器
    socket.send_to(data.as_bytes(), server_address).map_err(|err| err.to_string())?;
    // 接收来自服务器的响应
    let mut buffer = [0; 1024];
    let (bytes_received, _) = socket.recv_from(&mut buffer).map_err(|err| err.to_string())?;
    let response = std::str::from_utf8(&buffer[..bytes_received])
        .map_err(|err| err.to_string())
        .map(|s| s.to_string())?;

    Ok(response)
}

#[tauri::command]
fn msg_listener(window: Window) {
    std::thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:8080").expect("Failed to bind UDP socket");
        let mut buffer = [0u8; 4096];
        loop {
            let (num_bytes, src_addr) = socket.recv_from(&mut buffer).expect("Failed to receive message");
            let message = String::from_utf8_lossy(&buffer[..num_bytes]);
            window.emit("msg_listener", Payload { data: message.into(), address: src_addr.to_string() }).unwrap();
            socket.send_to("ok".as_bytes(), src_addr).expect("Failed to send response");
        }
    });
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![msg_sender,msg_listener])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
